/*
 *  $Id: Move.cs 1233 2010-12-18 17:54:48Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System.Collections.Generic;

using Nereal.Serialization;

namespace Ragima {
    /// <summary>
    /// Тип цели: место для перемещения существа.
    /// </summary>
    public abstract class MoveTarget : TargetType {
        protected Creature _creature;

        public MoveTarget(Creature creature) {
            _creature = creature;
        }

        private const int LeftNumber = 0;
        private const int RightNumber = Constants.FieldSize - 1;
        private int LeftMove {
            get { return _creature.CanFly || _creature.Number == LeftNumber ? LeftNumber : _creature.Number - 1; }
        }
        private int RightMove {
            get { return _creature.CanFly || _creature.Number == RightNumber ? RightNumber : _creature.Number + 1; }
        }

        public bool CanMove {
            get { return _creature.State == CreatureState.Untapped && _creature.CanMove; }
        }

        public override void Cancel() {
            if (Request != null)
                Request.Player.ResetSelection();
        }

        public override int GetCount(AbstractObject caster) {
            if (!CanMove)
                return 0;
            int count = 0, i = LeftMove, end = RightMove;
            while (i <= end) {
                if (caster.Owner.GetCreature(i) == null)
                    count++;
                i++;
            }
            return count;
        }

        public override IEnumerable<Region> GetRegions() {
            if (CanMove) {
                int i = LeftMove, end = RightMove;
                while (i <= end) {
                    if (Request.Player.GetCreature(i) == null)
                        yield return new CreatureMoveRegion(i);
                    i++;
                }
            }
        }

        public override TargetArgs GetArgs(Region region) {
            var cmr = region as CreatureMoveRegion;
            return cmr != null ? new MoveTargetArgs(Request.Player, Request.Caster, cmr.Place) : base.GetArgs(region);
        }
    }

    /// <summary>
    /// Регион, определяющий место для перемещения существа
    /// </summary>
    public class CreatureMoveRegion : Region {
        private int _to;

        public CreatureMoveRegion(int to) : base(Constants.GetRowRect(to, 2)) {
            _to = to;
        }

        public int Place {
            get { return _to; }
        }

        public override void Draw() {
            Data.CardSelect1.Draw(Rect.Location);
        }

        public override void OnClick() {
            Game.Current.Target.ClickRegion(this);
        }
    }

    public abstract class CreatureActionTargetArgs : TargetArgs {
        public CreatureActionTargetArgs() {
        }
        public CreatureActionTargetArgs(Player player, AbstractObject caster) : base(player, caster) {
        }

        public void DoAction() {
            var cr = Caster as Creature;
            if (cr != null)
                DoAction(cr);
        }

        protected abstract void DoAction(Creature cr);
    }

    [TypeId("move")]
    public class MoveTargetArgs : CreatureActionTargetArgs {
        [XmlName("place")]
        public int Place;

        public MoveTargetArgs() {
        }
        public MoveTargetArgs(Player player, AbstractObject caster, int place) : base(player, caster) {
            Place = place;
        }

        protected override void DoAction(Creature cr) {
            cr.MoveTo(Place);
        }
    }
}
